/**
 * @file msg_queue.c
 * @author TimeChicken (https://gitee.com/Time--Chicken)
 * @brief 消息队列管理服务函数实现
 * @version 0.1
 * @date 2021-08-23
 * 
 * @copyright Copyright (c) 2021
 * 
 */
#include "msg_queue.h"

msg_queue_manage msg_queue_manager; //全局变量消息队列管理者

void msg_manage_init(void)
{
    msg_queue_manager.msg_count = 0; //队列数量初始化为零
    msg_queue_manager.head = NULL;
    msg_queue_manager.tail = NULL;
}

/**
 * @brief 出队
 * 
 * @return msg_queue_node* 失败返回NULL，成功返回出队的节点
 */
msg_queue_node *msg_manage_out()
{
    if (msg_queue_manager.head == NULL)
        return NULL;
    msg_queue_node *res = msg_queue_manager.head;
    msg_queue_manager.head = msg_queue_manager.head->next;
    msg_queue_manager.msg_count--;
    if (msg_queue_manager.head == NULL)
        msg_queue_manager.tail == NULL;
    return res;
}

/**
 * @brief 入队
 * 
 * @param node 插入的节点
 * @return int* 成功返回0，失败返回1个负值
 */
int msg_manage_in(msg_queue_node *node)
{
    if (node == NULL)
        return -1;
    if (msg_queue_manager.head == NULL) //如果队列为空
    {
        msg_queue_manager.head = node;
        msg_queue_manager.tail = node;
    }
    else //如果队列不为空
    {
        msg_queue_manager.tail->next = node;
        msg_queue_manager.tail = msg_queue_manager.tail->next; //尾巴后移
    }
    msg_queue_manager.msg_count++;
    return 0;
}

/**
 * @brief 数据包转消息节点
 * 
 * @param node 消息队列节点
 * @return data_packet* 转换后的数据包
 */
data_packet *msgQueueNode_to_dataPacket(msg_queue_node *node)
{
    return node->data;
}

/**
 * @brief 消息节点转数据包
 * 
 * @param d_p 数据包结构体
 * @return msg_queue_node* 新的消息队列节点，失败返回NULL
 */
msg_queue_node *dataPacket_to_msgQueueNode(data_packet *d_p)
{

    msg_queue_node *o_node = malloc(sizeof(msg_queue_node));
    if(o_node == NULL)
        return NULL;
    o_node->next = NULL;
    o_node->data = d_p;
    return o_node;
}

/**
 * @brief 出队直接返回出队的数据包
 * 
 * @return data_packet* 出队的数据包，NULL返回失败 
 */
data_packet *msgQueue_out_dataPacket()
{
    msg_queue_node *out_node = msg_manage_out();
    if(out_node == NULL)
        return NULL;
    else
        return out_node->data;
}

/**
 * @brief 传入数据包直接入队
 * 
 * @param d_p 数据包地址
 * @return int 成功返回0，错误返回负值
 */
int msgQueue_in_dataPacket(data_packet *d_p)
{
    if(d_p == NULL)
        return -1;
    msg_queue_node *o_node = malloc(sizeof(d_p));
    if(o_node == NULL)
        return -1;
    o_node->data = d_p;
    o_node->next = NULL;
    msg_manage_in(o_node);
    return 0;
}

/**
 * @brief 释放消息队列，但也有可能不释放
 * 
 */
void msg_manage_uninit(void)
{
    // pass
}